home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / util / misc / hackertest.lha / Quest.rexx < prev    next >
OS/2 REXX Batch file  |  1992-11-22  |  10KB  |  441 lines

  1. /* Question program $VER: Quest 0.2 1992-06-19  E. Lundevall */
  2. parse arg qname
  3. options results
  4.  
  5. scores. = ''
  6. questions. = ''
  7.  
  8. if ~open(qf,qname,'Read') then do
  9.     say 'Hey,' qname 'is not where it should be!'
  10.     exit 10
  11.     end
  12.  
  13. say 'Reading from question file...(Zzzzz...)'
  14. scmatch = 'Scores:'
  15. qmatch  = 'Questions:'
  16. imatch  = 'Initial:'
  17.  
  18. keepGoing = 3
  19.  
  20. do until keepGoing = 0
  21.     do until line = scmatch | line = qmatch | line = imatch
  22.         line = readln(qf)
  23.         end
  24.  
  25.         keepGoing = keepGoing - 1
  26.         select
  27.             when line = scmatch then do    /* Read the score section */
  28.                 call GetScores
  29.                 scresult = result
  30.                 end
  31.  
  32.             when line = qmatch then do     /* Read the questions */
  33.                 call GetQuestions
  34.                 qresult = result
  35.                 end
  36.  
  37.             when line = imatch then do     /* Read section with initial msg */
  38.                 call GetInitial
  39.                 iresult = result
  40.                 end
  41.             end
  42.         end
  43. call close(qf)
  44.  
  45. if scresult || qresult || iresult ~= 'OkOkOk' then do
  46.     say 'Sorry, the question file seems to be corrupt.'
  47.     exit 10
  48.     end
  49.  
  50. call WriteInitial      /* Greet the user, ask questions, show highscores */
  51. call AskQuestions
  52. theScore = result
  53. call ShowScore(theScore)
  54. theText = result
  55.                          /* Possibly add score to highscore file */
  56. highscores. = ''
  57. call ReadHighScore(qname || '.scores')
  58. call AddHighScore(theScore,theText)
  59. call ShowHighScore(stdout)
  60. say 'Do you want to add this score in the highscore file?'
  61. parse upper pull ans
  62. if left(ans,1) = 'Y' then do
  63.     if open(sf,qname || '.scores','Write') then do
  64.         call ShowHighScore(sf)
  65.         call close(sf)
  66.         end
  67.     else do
  68.         say 'Could not open score file...'
  69.         end
  70.  
  71.     end
  72.  
  73.  
  74. exit 0
  75.  
  76.  
  77. /* Show greeting message */
  78.  
  79. WriteInitial: procedure expose initial.
  80.  
  81. call writech(stdout,'0c'x) /* Clear window */
  82. do i = 1 to initial.0
  83.     say initial.i
  84.     end
  85. say
  86. return
  87.  
  88.  
  89.  
  90. /* Read greeting message from question file */
  91.  
  92. GetInitial: procedure expose initial. qf
  93. keepGoing = 1
  94. i = 1
  95.  
  96. do while keepGoing = 1
  97.     line = readln(qf)
  98.  
  99.     select
  100.         when line = '' then do /* This is added because empty line does  */
  101.             initial.i = ''     /* not enter the otherwise part otherwise */
  102.             i = i + 1
  103.             end
  104.         when left(line,2) = '//' | length(strip(line)) = 0 then
  105.             iterate
  106.         when left(line,4) = '::::' then
  107.             keepGoing = 0
  108.         otherwise do
  109.             initial.i = line
  110.             i = i + 1
  111.             end
  112.         end
  113.     end
  114. initial.0 = i - 1
  115. return 'Ok'
  116.  
  117.  
  118.  
  119.  
  120. /* Read score intervals from question file */
  121.  
  122. GetScores: procedure expose scores. qf
  123. keepGoing = 1
  124. i = 1
  125.  
  126. do while keepGoing = 1
  127.     line = readln(qf)
  128.     select
  129.         when left(line,2) = '//' | length(strip(line)) = 0 then
  130.             iterate
  131.         when left(line,4) = '::::' then
  132.             keepGoing = 0
  133.         otherwise do
  134.             parse var line low '-' high ':' text
  135.             scores.i.lo = strip(low)
  136.             scores.i.hi = strip(high)
  137.             scores.i.txt = strip(text)
  138.             i = i + 1
  139.             end
  140.         end
  141.     end
  142. scores.0 = i - 1
  143. return 'Ok'
  144.  
  145.  
  146.  
  147.  
  148. /* Read questions from question file */
  149.  
  150. GetQuestions: procedure expose questions. qf
  151. keepGoing = 1
  152. i = 0
  153.  
  154.  
  155. do while keepGoing = 1
  156.     line = readln(qf)
  157.     select
  158.         when (left(line,2) = '//' | length(strip(line)) = 0) then
  159.             iterate
  160.  
  161.         when left(line,4) = '::::' then
  162.             keepGoing = 0
  163.  
  164.         when index(word(line,1),':') ~= 0 then do  /* Start of question */
  165.             parse var line num ':' qtext
  166.             i = i + 1
  167.             qtext = strip(qtext)
  168.             if word(qtext,1) = '*' then do   /* check if multiple choices */
  169.                 qtext = subword(qtext,2)     /* is allowed for the answer */
  170.                 questions.num.multi = 1
  171.                 end
  172.             else
  173.                 questions.num.multi = 0
  174.             questions.num.txt = strip(qtext)
  175.             answer = 0
  176.             end
  177.  
  178.         when word(line,1) = '*' then do      /* Get choice line */
  179.             parse var line '*' points text '=>' nextnum
  180.             answer = answer + 1
  181.             questions.num.answer.point = strip(points)
  182.             questions.num.answer.txt = strip(text)
  183.             if nextnum = '' then                  /* Skip to other question */
  184.                 nextnum = num + 1                 /* if this one is chosen  */
  185.             questions.num.answer.next = strip(nextnum)
  186.             questions.num.answernum = answer
  187.             end
  188.         end
  189.     end
  190. questions.0 = i
  191. return 'Ok'
  192.  
  193.  
  194.  
  195. /* Ask a question */
  196.  
  197. AskQuestions: procedure expose questions.
  198. myScore = 0
  199. nextQuest = 1
  200.  
  201. do while nextQuest ~= -1
  202.     mul = questions.nextQuest.multi
  203.     call ShowQuestion(mul)
  204.  
  205.     gotAnswer = 0
  206.     do until gotAnswer
  207.         call writech(stdout,'Answer: ')
  208.         parse pull answer
  209.  
  210.         select                     /* Check for special commands or answers */
  211.             when answer = '' then
  212.                 iterate
  213.  
  214.             when  'QUIT' = upper(word(answer,1)) then do
  215.                 nextQuest = -1
  216.                 gotAnswer = 1
  217.                 end
  218.  
  219.             when 'LEFT' = upper(word(answer,1)) then do
  220.                 say 'We got' questions.0 - nextQuest 'questions left, at most.'
  221.                 end
  222.  
  223.             when 'AGAIN' = upper(word(answer,1)) then do
  224.                 call ShowQuestion(mul)
  225.                 end
  226.  
  227.             otherwise do  /* Got answer, check if valid */
  228.                 answer = Unique(answer)
  229.                 gotAnswer = CheckAnswer(1 questions.nextQuest.answernum mul answer)
  230.                 if gotAnswer = 0 then do
  231.                     say 'Answer not valid, do it again...'
  232.                     say
  233.                     end
  234.                 end
  235.             end
  236.         end
  237.     end
  238.  
  239. return myScore   /* Return score we got from this question */
  240.  
  241.  
  242.  
  243.  
  244. /* Show the question text and the choices */
  245.  
  246. ShowQuestion: procedure expose questions. nextQuest
  247. parse arg mul
  248.  
  249. say
  250. say questions.nextQuest.txt
  251. if mul then
  252.   say '(Multiple choices possible)'
  253.     say
  254.     do i = 1 to questions.nextQuest.answernum
  255.         say i':' questions.nextQuest.i.txt
  256.         end
  257. return
  258.  
  259.  
  260.  
  261. /* Show the users score and what "level" that means */
  262.  
  263. ShowScore: procedure expose scores.
  264. parse arg score
  265.  
  266. res = ''
  267. say 'You got' score 'points.'
  268. say
  269. call writech(stdout,'That means...')
  270.  
  271. oki = 0
  272. do i = 1 to scores.0
  273.     if score <= scores.i.hi & score >= scores.i.lo then do
  274.         res = scores.i.txt
  275.         say res
  276.         oki = 1
  277.         leave
  278.         end
  279.     end
  280.  
  281. if ~oki then
  282.     say 'Can not find an appropriate entry for you.'
  283.  
  284. say
  285. say 'These are the possible scores:'
  286. do i = 1 to scores.0
  287.     say AddSpace(scores.i.lo,6) '-' AddSpace(scores.i.hi,6) ' :' scores.i.txt
  288.     end
  289. say
  290. return res
  291.  
  292.  
  293.  
  294.  
  295. /* Check if answer is valid (in range, that is) */
  296. CheckAnswer: procedure expose questions. nextQuest myScore
  297. parse arg  lo hi mul answer
  298. res = 0
  299. score = 0
  300.  
  301. if ~mul then
  302.     answer = word(answer,1)
  303.  
  304. do i = 1 to words(answer)        /* Check if each answer is numeric and */
  305.     a = strip(word(answer,i))    /* in range */
  306.     if datatype(a) = 'NUM' then do
  307.         if a >= lo  & a <= hi then do
  308.             score = score + questions.nextQuest.a.point
  309.             res = res + 1
  310.             end
  311.         end
  312.     end
  313.  
  314. if res = words(answer) then do   /* If all answers are valid, say it is ok */
  315.     res = 1                      /* and add the score. Get next question   */
  316.     myScore = myScore + score
  317.     nextQuest = strip(questions.nextQuest.a.next)
  318.     end
  319. else
  320.     res = 0
  321. return res
  322.  
  323.  
  324.  
  325. /* Read high score file */
  326.  
  327. ReadHighScore: procedure expose highscores.
  328. parse arg fil
  329.  
  330. i = 0
  331. highscores.nscores = 0
  332. highscores.first = -1
  333. if open(sf,fil,'Read') then do
  334.     call readln(sf)
  335.     do until eof(sf)
  336.         line = readln(sf)
  337.         parse var line dummy thescore user '::' info
  338.         if dummy ~= '' then do
  339.             i = i + 1
  340.             highscores.i.score = thescore
  341.             highscores.i.name = strip(user)
  342.             highscores.i.txt = strip(info)
  343.             highscores.i.next = i + 1
  344.             end
  345.         end
  346.     call close(sf)
  347.     highscores.i.next = -1
  348.     highscores.first = 1
  349.     highscores.nscores = i
  350.     end
  351. return
  352.  
  353.  
  354.  
  355. /* Show the highscores */
  356.  
  357. ShowHighScore: procedure expose highscores. qname scores.
  358. parse arg filehandle
  359.  
  360. call writeln(filehandle,'Top scores for' qname)
  361. i = highscores.first
  362. j = 0
  363. do until i = -1
  364.     call writech(filehandle,AddSpace(j,4) AddSpace(highscores.i.score,6))
  365.     call writech(filehandle,AddSpace(highscores.i.name,30,2))
  366.     call writeln(filehandle,'::' highscores.i.txt)
  367.     i = highscores.i.next
  368.     j = j + 1
  369.     end
  370. return
  371.  
  372.  
  373.  
  374. /* Add new score to the highscores */
  375.  
  376. AddHighScore: procedure expose highscores.
  377. thescore = arg(1)
  378. scoretxt = arg(2)
  379.  
  380. say 'What is your name?'
  381. parse pull thename
  382.  
  383. num = highscores.nscores
  384. highscores.nscores = highscores.nscores + 1
  385. highscores.0.score = thescore
  386. highscores.0.name = thename
  387. highscores.0.txt = scoretxt
  388. highscores.0.next = -1
  389.  
  390. prev = -1
  391. i = highscores.first
  392. do while i ~= -1
  393.     if thescore > highscores.i.score then do
  394.         highscores.0.next = i
  395.         if prev ~= -1 then
  396.             highscores.prev.next = 0
  397.         leave
  398.         end
  399.     prev = i
  400.     i = highscores.i.next
  401.     end
  402.  
  403. if prev = -1 then     /* If we got the first/top score */
  404.     highscores.first = 0
  405. else if highscores.0.next = highscores.prev.next then
  406.     highscores.prev.next = 0               /* if we got the lowest score */
  407.  
  408. return
  409.  
  410.  
  411.  
  412. /* Add some space to a text */
  413.  
  414. AddSpace: procedure
  415. txt = arg(1)
  416. num = arg(2)
  417. start = arg(3)
  418. if start = '' then
  419.     start = 1
  420. return overlay(txt,copies(' ',num),start)
  421.  
  422.  
  423.  
  424. /* Remove doublets of an answer */
  425. Unique: procedure
  426. parse arg answers
  427.  
  428. tmp = ''
  429. do until answers = ''
  430.     first = word(answers,1)
  431.     tmp = tmp first
  432.     answers = delword(answers,1,1)
  433.     do i = 1 to words(answers)
  434.         if word(answers,i) = first then do
  435.             answers = delword(answers,i,1)
  436.             i = i - 1
  437.             end
  438.         end
  439.     end
  440. return strip(tmp)
  441.